package itheima.puzzle;

import java.util.Random;
import java.util.Scanner;

public class NumberPuzzle {
    public static void main(String[] args) {
        // 定义变量，记录空格位置
        int size = 4;
        int[] emptyPos = {3,3};
        // 1.生成棋盘（二维数组）
        int [][] boards = initBoard(size,emptyPos);
        do {
            // 2.打印棋盘
            printBoard(boards);

            // 3.键盘录入移动方向
            String direction = nextDiraction();
            // 4.移动棋子
            tryMove(boards, emptyPos, direction);
            // 5.判断是否获胜
            boolean win = isResolved(boards);
            if(win){
                System.out.println("恭喜你，胜利了！");
                break;
        }
        }while (true);
    }

    public static int[][] initBoard(int size,int[] emptyPos) {
        // 1.动态生成有序棋盘，棋盘大小为size*size
        int[][] boards = new int[size][size];
        for (int i = 0; i < boards.length; i++) {
            int[] row = boards[i];
            for (int j = 0; j < row.length; j++) {
                row[j] = i * row.length + j + 1;
            }
        }
        // 2.打乱棋盘(模拟人移动棋子)
        String[] directions = {"w","s","a","d"};
        Random random = new Random();
        for (int i = 0; i < 1000; i++) {
            // 2.1随机生成一个移动方向(随机生成一个0-3的数字，然后以数字为索引去directions中获取方向)
            int index = random.nextInt(4);
            String direction = directions[index];
            // 2.2移动棋子
            tryMove(boards, emptyPos, direction);
        }
        return boards;
    }

    public static boolean isResolved(int[][] boards) {
        // 1.定义一个变量，用来去判断棋子值是否从0-15递增
        int num = 1;
        // 2.循环遍历每一个棋子，判断是否与num一致，最后一个除外，最后一个应该为0
        for (int i = 0; i < boards.length; i++) {
           int[] row = boards[i];
            for (int j = 0; j < row.length; j++) {
                if (row[j] != num && !(row[j] == 0 && num == 16) ) {
                    return false;
                }
                num++;
            }
        }
        // 3.所有棋子都正确
        return true;
    }

    public static void tryMove(int[][] boards, int[] emptyPos, String direction) {
        // 1.判断用户输入的方向，找到对应目标棋子的offset
        int[] offset = switch (direction){
            case "w" -> new int[]{1,0};
            case "s" -> new int[]{-1,0};
            case "a" -> new int[]{0,1};
            case "d" -> new int[]{0,-1};
            default -> new int[0];
        };
        if(offset.length == 0 ){
            System.out.println("输入方向有误！");
            return;
        }
        // 2.计算目标棋子的索引
        // 2.1获取空格位置索引
        int emptyRow = emptyPos[0];
        int emptyCol = emptyPos[1];
        // 2.2计算目标棋子索引
        int targetRow = emptyRow + offset[0];
        int targetCol = emptyCol + offset[1];
//        System.out.println("目标索引是:"+boards[targetRow][targetCol]);
        // 2.3判断角标是否越界
        if(targetRow < 0 || targetRow > 3 || targetCol < 0 || targetCol > 3){
            System.out.println("输入方向有误！");
            return;
        }

        // 3.将空格与目标棋子交换位置
        // 3.1把目标棋子的值放到空格位置
        boards[emptyRow][emptyCol] = boards[targetRow][targetCol];
        // 3.2把目标棋子值改成0
        boards[targetRow][targetCol] = 0;

        // 4.更新空格位置的索引值
        emptyPos[0] = targetRow;
        emptyPos[1] = targetCol;
    }

    public static String nextDiraction() {
        // 1.创建Scanner对象
        Scanner scanner = new Scanner(System.in);
        // 2.提示用户输入方向
        System.out.println("请输入移动方向（w：上，s：下，a：左，d：右）：");
        // 3.录入方向
        return scanner.next();
    }

    public static void printBoard(int[][] boards) {
        System.out.println("--------------------");
        for (int i = 0; i < boards.length; i++) {
            int[] row = boards[i];
            System.out.print("| ");
            for (int j = 0; j < row.length; j++) {
                int num = row[j];
                String numStr = num == 0 ? "  " : (num < 10 ? num+ " " : num + "");
                System.out.print(numStr + " | ");
            }
            System.out.println();
            System.out.println("--------------------");
        }
    }

}
